/////precompiled////////
#include "precompiled.h"
////////////////////////


#include "frm_control_TLine.h"
#include "frm_control_TFrame.h"

using namespace frm;
using namespace control;

// TLine //////////////////////////////////////////////////////////////////////

//
void TLine::TStyle::SetFromParent(frm::TStyle *Parent_)
{
  if (!Parent_) {
    return;
  }

  TStyle *Parent = dynamic_cast<TStyle*>(Parent_);
  
  Normal.Filler.SetFromParent(Parent->Normal.Filler);
  Normal.Cursor.SetFromParent(Parent->Normal.Cursor);
  Normal.Border.SetFromParent(Parent->Normal.Border);

  Selected.Filler.SetFromParent(Parent->Selected.Filler);
  Selected.Cursor.SetFromParent(Parent->Selected.Cursor);
  Selected.Border.SetFromParent(Parent->Selected.Border);

  Focused.Filler.SetFromParent(Parent->Focused.Filler);
  Focused.Cursor.SetFromParent(Parent->Focused.Cursor);
  Focused.Border.SetFromParent(Parent->Focused.Border);
}

//
svl::TInfoParam TLine::TStyle::AddInfoTo(svl::TInfoParam Info)
{
  return frm::TStyle::AddInfoTo(Info)
   .Add("Normal"   ,Normal)
   .Add("Selected",Selected)
   .Add("Focused" ,Focused)
  ;
}

//
TLine::TLine(TWindow &Window) : TPanel(Window)//,childWidth(*this)
{
/***********************
  struct TStyle : public TLine::TStyle
  {
    TStyle()
    {
      //Focused.Filler.Set(frm::TFiller::TFrameRect(192,192,0));
      
      Focused.Filler.Set(frm::TFiller::TArray()
        .Add(frm::TFiller::TColor    (210,210,210))
        .Add(frm::TFiller::TFrameRect(192,192,0))
      );
    }    
  };
************************/  
  
  static TStyle Style; SetStyle(Style);

  Width_Fixed(200).Height_ChildrenMaxBase().DirectChildren_Horz()
   .WAlignChildren_Begin().HAlignChildren_BeginBase();
}

//
TLine::~TLine()
{
  //DeleteChildren();
}

//
TLine &TLine::SetStyle(TStyle &V)
{
  style = &V; 
  
  if (IsVisibleInParents())
  {
    if (Focus_IsEnter()) { 
      TPanel::UpdateStyle(V.Focused); 
    }
    else if (Select_IsEnter()) { 
      TPanel::UpdateStyle(V.Selected); 
    }
    else { 
      TPanel::UpdateStyle(V.Normal); 
    }
  }
  else { 
    TPanel::SetStyle(V.Normal); 
  }
  
  return *this;
}

//
bool TLine::SplitInComponentPos(TMergeSplit &MS,TLine &ToLine,TPanel *ComponentSplit,int ComponentSplitPos)
{
  for (int N = 0; N < GetChildrenCount(); N++)
  {
    TComponent &Child = GetChild(N); if (&Child == ComponentSplit) {
      TComponent *NewComp = ComponentSplit->TComponent_SplitInPos(MS,ComponentSplitPos); 
      
      if (NewComp) { 
        ToLine.AddChildLast(NewComp,true); if (N+1 < GetChildrenCount()) { 
          MoveChildrenTo(N+1,GetChildrenCount()-1, 1,&ToLine);
        }
      }
      else { 
        MoveChildrenTo(N,GetChildrenCount()-1, 0,&ToLine); 
      }
      return true;  
    }
  }
  return false;
}

//
bool TLine::Split(TMergeSplit &MS,TLine &To,int Width)
{
  TTempDisableCalcSize D1(this);
  TTempDisableCalcSize D2(&To);

  Width -= max( 0,GetWOrdinate().GetBorder().GetSize() );

  int W = 0; 
  
  for (int N = 0; N < GetChildrenCount(); N++) {
    TPanel &Child = dynamic_cast<TPanel&>(GetChild(N));
    int ChildWidth = Child.GetWidth();

    W += ChildWidth; if (W > Width) {
      TComponent *NewCom = Child.TComponent_SplitInSize( MS,ChildWidth - (W - Width) );
      
      if (NewCom) {
        if (N + 1 < GetChildrenCount()) { 
          MoveChildrenTo(N+1,GetChildrenCount()-1, 0,&To); 
        }
        To.AddChildFirst(NewCom,true);
      }
      else {
        if (N > 0) { 
          MoveChildrenTo(N,GetChildrenCount()-1, 0,&To); 
        }
        else if (N + 1 < GetChildrenCount()) { 
          MoveChildrenTo(N+1,GetChildrenCount()-1, 0,&To); 
        }
        else { 
          return false;
        }
      }
      return true;
    }
  }
  return false;
}

//
void TLine::Merge(TMergeSplit &MS,TLine &From)
{
  TTempDisableCalcSize D1(this);
  TTempDisableCalcSize D2(&From);

  if (MS.Focus == &From) {
    MS.Focus = this;
  }

  if (GetChildrenCount() && From.GetChildrenCount()) {
    TPanel &ThisLast  = dynamic_cast<TPanel&>(GetChild(GetChildrenCount()-1));
    TPanel &FromFirst = dynamic_cast<TPanel&>(From.GetChild(0));

    if (ThisLast.TComponent_MergeFrom(MS,&FromFirst)) {
      GetWindow().PanelDeletor.Add(&From,0);
      //From.DeleteChild(0);
    }
  }
  
  if (From.GetChildrenCount()) {
    From.MoveChildrenTo( 0,From.GetChildrenCount()-1, GetChildrenCount(),this );
  }
}

//
void TLine::TComponent_KeyboardKey(grf::TKeyboardKey &KeyboardKey)
{
  if (KeyboardKey.State == grf::TKeyboardKey::EState_Down)
  {
/***************
    if (KeyboardKey.Key == VK_RETURN && Options.EnProcKeyReturn)
    {
      TRow *Row = dynamic_cast<TRow*>(SearchThisOrParent(TRow::TType())); if (Row)
      {
        TBeginPaint P(this); 
          Row->UpdateExpand(!Row->GetExpand());
        return;
      }
    }
****************/    
    if (KeyboardKey.Key == VK_RIGHT)
    {
      TPanel *CurrFocus = Focus_GetEnter();
      
      TPanel *NewFocus = SearchNextChildFocusEnable
        (CurrFocus->Type(),CurrFocus);
      if (!NewFocus) { return;}

      NewFocus->Focus_EnterByPos(0);
      return;
    }
    else if (KeyboardKey.Key == VK_LEFT)
    {
      TPanel *CurrFocus = Focus_GetEnter();

      TPanel *NewFocus = SearchPrevChildFocusEnable
        (CurrFocus->Type(),CurrFocus);
      if (!NewFocus) { return;}

      NewFocus->Focus_EnterByPos(NewFocus->TComponent_GetCaretMaxPos());
      return;
    }
  }
  TPanel::TComponent_KeyboardKey(KeyboardKey);
}

//
void TLine::TComponent_SelectEnter()
{
  TPanel::TComponent_SelectEnter();

  if (!Focus_IsEnter()) { 
    TPanel::UpdateStyle(style->Selected);
  }
}

//
void TLine::TComponent_SelectExit()
{
  TPanel::TComponent_SelectExit();
  TPanel::UpdateStyle(style->Normal);
}

//
void TLine::TComponent_FocusEnter()
{
  TPanel::TComponent_FocusEnter();

  TPanelSelect *Select = GetSelectThisOrParent(); 
  
  if (Select) { 
    Select->SetEnter(this);
  }
  TPanel::UpdateStyle(style->Focused);
}

//
void TLine::TComponent_FocusExit()
{
  TPanel::TComponent_FocusExit();

  TPanelSelect *Select = GetSelectThisOrParent();
  
  if (Select && Select->IsEntered(this)) { 
    TPanel::UpdateStyle(style->Selected);
  }
  else { 
    TPanel::UpdateStyle(style->Normal);
  }
}

//
void TLine::TComponent_MouseEnter()
{
  TPanel::TComponent_MouseEnter();
  //::MessageBeep(0);
}

//
void TLine::TComponent_MouseExit()
{
  TPanel::TComponent_MouseExit();
}

//
void TLine::TComponent_Mouse(TMouse Mouse)
{
  //::MessageBeep(0);
  switch (Mouse.State)
  {
    case grf::TMouse::EState_LButtonDown: if
    (
      //Mouse.TopComponent == this &&
      TComponent_FocusEnable() && 
      Mouse.TopComponent->TComponent_TransparentForFocus()
    )
    {
      Focus_EnterByPos(0); return;
    }
    break;
  }
  TPanel::TComponent_Mouse(Mouse);
}

//
void TLine::TComponent_SetCaretByX(TGeometryRect &GRect,int XClient)
{
  grf::TCaret &Caret = GetFocus().Caret;

  Caret.Destroy();
  Focus_SetPos(0);
}

//
void TLine::TComponent_SetCaretByPos(TGeometryRect &GRect,int Pos)
{
  grf::TCaret &Caret = GetFocus().Caret;

  Caret.Destroy();
  Focus_SetPos(0);
}

//
void TLine::TComponent_ScrollToVisible(TGeometryRect &GRect)
{
  TFrame *CurrFrame = dynamic_cast<TFrame*>(SearchParent(TFrame::TType())); if (CurrFrame)
  {
    TGeometryRect GRectClient; GetWindow().CalcGeometryRect
      (CurrFrame->Client,GRectClient);
    grf::TRect R;
      R.Left   = GRectClient.RThisVisible.Left;
      R.Top    = GRect.RThis.Top;
      R.Width  = GRectClient.RThisVisible.Width;
      R.Height = GRect.RThis.Height;
    CurrFrame->ScrollToVisibleRect(*this,R);
  }
}

//
void TLine::TComponent_InheritStyleFrom(TTableOfStyles &ParentStyles)
{ 
  TStyle *Style = dynamic_cast<TStyle*>(ParentStyles.SearchByEqualType(TStyle::TType())); if (Style) {
    SetStyle(*Style);
  }
}
